package com.jr.service.impl;

import com.jr.mapper.ParkingRecordsMapper;
import com.jr.mapper.PaymentsMapper;
import com.jr.service.ReportService;
import com.jr.vo.ReportVo;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

/**
 * 报表服务实现类
 * 实现日报、周报、月报、季报、年报的生成逻辑
 */
@Service
public class ReportServiceImpl implements ReportService {

    @Resource
    private ParkingRecordsMapper parkingRecordsMapper;

    @Resource
    private PaymentsMapper paymentsMapper;

    /**
     * 日期格式化工具
     */
    private final SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");

    @Override
    public ReportVo generateReport(ReportVo reportVo) {
        Integer status = reportVo.getStatus();
        Date date = reportVo.getDate();

        // 创建返回对象
        ReportVo result = new ReportVo();
        result.setStatus(status);
        result.setDate(date);

        if (status == 0) {
            // 日报处理逻辑
            handleDailyReport(result, date);
        } else {
            // 周报、月报、季报、年报处理逻辑
            handlePeriodReport(result, date, status);
        }

        return result;
    }

    /**
     * 处理日报逻辑
     */
    private void handleDailyReport(ReportVo result, Date date) {
        // 设置日期字符串
        String dates = dateFormat.format(date);
        result.setDates(dates);

        // 查询车流量
        Integer carNumber = parkingRecordsMapper.countByEntryOrExitDate(date);
        result.setCarNumber(carNumber);

        // 查询总收入
        List<Integer> recordIds = parkingRecordsMapper.findIdsByEntryOrExitDate(date);
        Double money = paymentsMapper.sumAmountByRecordIds(recordIds);
        if (money == null) {
            money = 0.0;
        }
        result.setMoney(money);

        // 计算单车平均收入
        Double price = 0.0;
        if (carNumber != null && carNumber > 0) {
            price = money / carNumber;
        }
        result.setPrice(price);
    }

    /**
     * 处理周期报表逻辑（周报、月报、季报、年报）
     */
    private void handlePeriodReport(ReportVo result, Date date, Integer status) {
        // 计算日期范围
        Date endDate = calculateEndDate(date, status);
        String startDateStr = dateFormat.format(date);
        String endDateStr = dateFormat.format(endDate);
        String dates = startDateStr + "~~" + endDateStr;
        result.setDates(dates);

        // 查询车流量
        Integer carNumber = parkingRecordsMapper.countByDateRangeCondition(date, endDate);
        result.setCarNumber(carNumber);

        // 查询总收入
        List<Integer> recordIds = parkingRecordsMapper.findIdsByDateRangeCondition(date, endDate);
        Double money = paymentsMapper.sumAmountByDateRangeRecordIds(recordIds);
        if (money == null) {
            money = 0.0;
        }
        result.setMoney(money);

        // 计算单车平均收入
        Double price = 0.0;
        if (carNumber != null && carNumber > 0) {
            price = money / carNumber;
        }
        result.setPrice(price);
    }

    /**
     * 根据状态计算结束日期
     */
    private Date calculateEndDate(Date date, Integer status) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);

        switch (status) {
            case 1: // 周报：计算本周周六
                // Calendar类中，周日是1，周一是2，...，周六是7
                int daysUntilSaturday = 7 - calendar.get(Calendar.DAY_OF_WEEK);
                if (daysUntilSaturday < 0) {
                    daysUntilSaturday += 7;
                }
                calendar.add(Calendar.DAY_OF_MONTH, daysUntilSaturday);
                break;
            case 2: // 月报：计算本月最后一天
                calendar.set(Calendar.DAY_OF_MONTH, calendar.getActualMaximum(Calendar.DAY_OF_MONTH));
                break;
            case 3: // 季报：计算本季度最后一天
                int quarter = (calendar.get(Calendar.MONTH) / 3) + 1;
                int lastMonthOfQuarter = quarter * 3 - 1;
                calendar.set(Calendar.MONTH, lastMonthOfQuarter);
                calendar.set(Calendar.DAY_OF_MONTH, calendar.getActualMaximum(Calendar.DAY_OF_MONTH));
                break;
            case 4: // 年报：计算本年最后一天
                calendar.set(Calendar.MONTH, Calendar.DECEMBER);
                calendar.set(Calendar.DAY_OF_MONTH, calendar.getActualMaximum(Calendar.DAY_OF_MONTH));
                break;
            default:
                // 默认返回原日期
                break;
        }

        return calendar.getTime();
    }
}